<?php 

if( !isset($_SESSION) ) {
    session_start();
}

class KANDatabase {

    private $connection = NULL;
    private $hostname = NULL;
    private $databaseName;
    private $username;
    private $password;
    private $error = "";
    private $prefix;
    
    public function __construct() {
        // store the database information in the various class variables for later use
        $this->hostname = isset($_POST['dbhostname']) ? $_POST['dbhostname'] : "" ;
        $this->databaseName = isset($_POST['dbname']) ? $_POST['dbname'] : "" ;
        $this->username = isset($_POST['dbusername']) ? $_POST['dbusername'] : "";
        $this->password = isset($_POST['dbpassword']) ? $_POST['dbpassword'] : "";
        $this->prefix = isset($_POST['dbTablePrefix']) ? $_POST['dbTablePrefix'] : 
                isset($_SESSION['dbTablePrefix']) ? $_SESSION['dbTablePrefix'] : "";
    }

	/**
     * Runs the installation process for the KAN Database.
     *
     * @access	public
     * @return	boolean	True on success.
     * @since	1.0
     */
    public function doInstall() {
        
        // if the session variable for the hostname exists, then probability
        // the database has already been created is present, hence cancel
        // the install process early
        if( isset($_SESSION['hostname']) ) {
            return true;
        }

		// try to set up the database, if it has not already been set up.
        if( !$this->setupDatabase() ) {
            echo $this->error;
            return false;
        }

		// try to generate the Database Configuration file
        if( !$this->generateConfigurationFile() ) {
            return false;
        }

        return true;
    }

	/**
     * Sets up the KAN database. Creates it if not present, or populates it
	 * if present
     *
     * @access	protected
     * @return	boolean	True on success.
     * @since	1.0
     */
    protected function setupDatabase() {

        // Try to select the database. If it does not exist, then we will create the database
		// if we have a user with enough privelages.
        if( !mysql_select_db($this->databaseName, $this->getConnection()) ) {

        	// If the database is not yet created, create it.
            if( !$this->createDatabase() ) {
                $this->error .= "Failed To Create Database '" . $this->databaseName . "'.<br />";
                return false;
            }
			
        } else {
			// if the specified database exists, then we will just populate it with the data
			// now we need to load the content for the database
			$schema = '../sql/kan_schema.sql';
			if( !$this->populateDatabase($schema) ) {
				return false;
			}
		}
		
		
        // if the database setup completes successfully, then
        // store variables as Session Variables so we can get them even
        // if the page is refreshed in the process
        $_SESSION['hostname'] = $this->hostname;
        $_SESSION['databaseName'] = $this->databaseName;
        $_SESSION['dbusername'] = $this->username;
        $_SESSION['dbpassword'] = $this->password;
        $_SESSION['dbTablePrefix'] = $this->prefix;


        return true;
    }

	/**
     * Creates the database specified by the user
     *
     * @access	protected
     * @return	boolean	True on success.
     * @since	1.0
     */
    protected function createDatabase() {
        // Build the create database query.
        $query = 'CREATE DATABASE `' . $this->databaseName . '` ';

        mysql_query($query, $this->getConnection());

        if( mysql_error() != '' ) {
            $this->error .= mysql_error();
            return false;
        } else {
            mysql_select_db($this->databaseName, $this->getConnection());
        }

        // now we need to load the content for the database
        $schema = '../sql/kan_schema.sql';
        if( !$this->populateDatabase($schema) ) {
            return false;
        }

        return true;
    }

	/**
     * Gets the connection to the current database for the site
     *
     * @access	protected
     * @param	string	Path to the schema file.
     * @return	boolean	True on success.
     * @since	1.0
     */
    protected function getConnection() {
        if( $this->connection != NULL ) {
            return $this->connection;
        }

        $this->connection = mysql_connect($this->hostname, $this->username, $this->password);

        return $this->connection;
    }

    /**
     * Method to import a database schema from a file.
     *
     * @access	public
     * @param	string	Path to the schema file.
     * @return	boolean	True on success.
     * @since	1.0
     */
    public function populateDatabase($schema) {
        // Initialize variables.
        $return = true;

        // Get the contents of the schema file.
        if (!($buffer = file_get_contents($schema))) {
            $this->error .= "Failed To Load Schema Installation File<br />";
            return false;
        }
        
        // replace all instances of <prefix> in the loaded SQL with the specified 
        // prefix for the installer
        $buffer = str_replace("<prefix>", $this->prefix, $buffer);

        // Get an array of queries from the schema and process them.
        $queries = $this->splitQueries($buffer);
        foreach ($queries as $query) {
            // Trim any whitespace.
            $query = trim($query);

            // If the query isn't empty and is not a comment, execute it.
            if (!empty($query) && ($query{0} != '#')) {
            	// Execute the query.
			
				/**
				 * UPDATED 2010-04-26 Francis Adu-Gyamfi
				 * Removed call to $this->getConnection() to enable this function be used
				 * in other installation classes without requiring the connection being used by this
				 * class, since the connection will not exist unless doInstall is called.
				 */
                mysql_query($query);

                // Check for errors.
                if (mysql_error() != '') {
                    $this->error .= mysql_error() . "<br />";
                    $return = false;
                }
            }
        }

        return $return;
    }

    /**
     * Method to split up queries from a schema file into an array.
     *
     * @access	protected
     * @param	string	SQL schema.
     * @return	array	Queries to perform.
     * @since	1.0
     */
    protected function splitQueries($sql) {
    // Initialize variables.
        $buffer		= array();
        $queries	= array();
        $in_string	= false;

        // Trim any whitespace.
        $sql = trim($sql);

        // Remove comment lines.
        $sql = preg_replace("/\n\#[^\n]*/", '', "\n".$sql);

        // Parse the schema file to break up queries.
        for ($i = 0; $i < strlen($sql) - 1; $i ++) {
            if ($sql[$i] == ";" && !$in_string) {
                $queries[] = substr($sql, 0, $i);
                $sql = substr($sql, $i +1);
                $i = 0;
            }

            if ($in_string && ($sql[$i] == $in_string) && $buffer[1] != "\\") {
                $in_string = false;
            }
            elseif (!$in_string && ($sql[$i] == '"' || $sql[$i] == "'") && (!isset ($buffer[0]) || $buffer[0] != "\\")) {
                $in_string = $sql[$i];
            }
            if (isset ($buffer[1])) {
                $buffer[0] = $buffer[1];
            }
            $buffer[1] = $sql[$i];
        }

        // If the is anything left over, add it to the queries.
        if (!empty($sql)) {
            $queries[] = $sql;
        }

        return $queries;
    }

    function generateConfigurationFile() {
        // find the database configuration path
        $currentPage = $_SERVER['PHP_SELF'];
        $endPos = strpos($currentPage, "install/");
        $siteRoot = substr($currentPage, 0, $endPos);
        $configPath = $_SERVER['DOCUMENT_ROOT'] . $siteRoot . 'assets/config/config.php';
		
		// if the configuration file already exists, we'll just overwrite the data
        
        $data = "<?php <br />";
        $data .= "# FileName='Connection_php_mysql.htm' <br />";
        $data .= "# Type='MYSQL' <br />";
        $data .= "# HTTP='true' <br />";
        $data .= '$hostname_config = "' . $this->hostname . '"; <br />';
        $data .= '$database_config = "' . $this->databaseName . '"; <br />';
        $data .= '$username_config = "' . $this->username . '"; <br />';
        $data .= '$password_config = "' . $this->password . '"; <br />';
        $data .= '$prefix_config = "' . $this->prefix . '"; <br /><br />';
        $data .= 'define("DB_HOST", $hostname_config ); <br />';
        $data .= 'define("DB_USER", $username_config ); <br />';
        $data .= 'define("DB_PASS", $password_config ); <br />';
        $data .= 'define("DB_NAME", $database_config ); <br />';
        $data .= 'define("DB_PREFIX", $prefix_config ); <br /><br />';
        $data .= '$config = mysql_connect($hostname_config, $username_config, $password_config) or trigger_error(mysql_error(),E_USER_ERROR); <br /><br />';
		$data .= 'mysql_select_db($database_config,$config); <br />';
        $data .= "?>";

        // prep the data string for proper line breaks
        $final = str_replace("<br />", "\r\n", $data);

        // save the content to file
        if( !file_put_contents($configPath, $final) ) {
            return false;
        }

        return true;
    }
}
?>